﻿#include "OperatorsMeshManager.h"

#include "GUIFrame/MainWindow.h"
#include "GUIFrame/PropertyWidget.h"
#include "GUIDialog/GUICalculateDialog/BoundaryWidget.h"
#include "GUIDialog/GUIMeshDialog/MeshResetNameDialog.h"
#include "GUIDialog/GUIMeshDialog/MeshAssemblyDialog.h"

#include "FITK_Kernel/FITKAppFramework/FITKAppFramework.h"
#include "FITK_Kernel/FITKAppFramework/FITKGlobalData.h"
#include "FITK_Kernel/FITKAppFramework/FITKAppSettings.h"
#include "FITK_Kernel/FITKAppFramework/FITKSignalTransfer.h"
#include "FITK_Interface/FITKInterfaceMeshGen/FITKMeshGenInterface.h"
#include "FITK_Interface/FITKInterfaceMeshGen/FITKAbstractMesherDriver.h"
#include "FITK_Interface/FITKInterfaceMeshGen/FITKAbstractMeshProcessor.h"
#include "FITK_Interface/FITKInterfaceMeshGen/FITKGeometryMeshSize.h"
#include "FITK_Interface/FITKInterfaceMeshGen/FITKRegionMeshSize.h"
#include "FITK_Interface/FITKInterfaceMeshGen/FITKRegionGeometryRefine.h"
#include "FITK_Kernel/FITKAppFramework/FITKGlobalData.h"
#include "FITK_Kernel/FITKAppFramework/FITKAppFramework.h"
#include "FITK_Interface/FITKInterfaceMesh/FITKUnstructuredFluidMeshVTK.h"
#include "FITK_Interface/FITKInterfaceMesh/FITKUnstructuredMeshVTK.h"
#include "FITK_Interface/FITKInterfaceFlowOF/FITKOFPhysicsData.h"
#include "FITK_Interface/FITKInterfaceFlowOF/FITKOFBoundary.h"
#include "FITK_Interface/FITKInterfaceFlowOF/FITKOFGeometryData.h"

#include "OperatorsInterface/GraphEventOperator.h"
#include "OperatorsInterface/TreeEventOperator.h"

#include "FITK_Kernel/FITKAppFramework/FITKAppFramework.h"
#include "FITK_Kernel/FITKAppFramework/FITKComponents.h"
#include "FITK_Interface/FITKInterfaceFlowOF/FITKFlowPhysicsHandlerFactory.h"
#include <QFile>
#include <QFileInfo>
#include <QDebug>

#include <QDir>


namespace ModelOper
{
    bool OperatorsMeshManager::execGUI()
    {
        EventOper::GraphEventOperator* graphOper = FITKOPERREPO->getOperatorT<EventOper::GraphEventOperator>("GraphPreprocess");
        if (graphOper == nullptr)return false;
        // 获取模型树控制器
        auto treeOper = Core::FITKOperatorRepo::getInstance()->getOperatorT<EventOper::TreeEventOperator>("ModelTreeEvent");
        if (treeOper == nullptr) return false;

        // 获取属性栏
        GUI::MainWindow* mainWindow = dynamic_cast<GUI::MainWindow*>(FITKAPP->getGlobalData()->getMainWindow());
        if (mainWindow == nullptr)return false;
        GUI::PropertyWidget* propertyWidget = mainWindow->getPropertyWidget();
        if (propertyWidget == nullptr)return false;
        
        if (_emitter == nullptr)return false;
        QString actionName = _emitter->objectName();
        if (actionName == "actionMesh") {
            // 获取单例
            auto meshGen = Interface::FITKMeshGenInterface::getInstance();
            auto manager = meshGen->getGeometryMeshSizeManager();
            // 网格划分
            auto meshDriver = meshGen->getMesherDriver();
            if (meshDriver == nullptr) return false;

            auto regionManager = meshGen->getRegionMeshSizeMgr();
            auto regionGeoRefManager = meshGen->getRegionGeometryRefineManager();
            bool runSnappy = false;
            if (regionManager && regionGeoRefManager) {
                runSnappy = (!(regionManager->getRigonByType(Interface::FITKAbstractRegionMeshSize::RegionType::RigonGeom).isEmpty()))
                    || regionGeoRefManager->getDataCount();
            }
            
            //工作路径获取
            QString workDir = "";
            if (FITKAPP->getAppSettings()) {
                workDir = FITKAPP->getAppSettings()->getWorkingDir();
            }
            if (workDir.isEmpty()) workDir = QApplication::applicationDirPath() + "/../WorkDir";

            //网格划分路径指定
            QString meshGenDir = workDir + "/case";

            meshDriver->setValue("WorkDir", meshGenDir);
            meshDriver->setValue("HasGeoMeshSize", runSnappy);
            meshDriver->startMesher();
            connect(meshDriver, &Interface::FITKAbstractMesherDriver::mesherFinished, [this,meshDriver] {
                disconnect(meshDriver, &Interface::FITKAbstractMesherDriver::mesherFinished, nullptr, nullptr);
                readMesh();
            });
        }
        else if (actionName == "actionClearMesh") {
            //清除网格数据
            auto globalData = FITKAPP->getGlobalData();
            if (globalData == nullptr)return false;
            Interface::FITKUnstructuredFluidMeshVTK* meshData = globalData->getMeshData< Interface::FITKUnstructuredFluidMeshVTK>();
            if (meshData == nullptr)return false;
            meshData->clearMesh();
            //FASTSIM的网格一并清除
            Interface::FITKUnstructuredMeshVTK* meshDataFASTSIM = globalData->getMeshDataFASTSIM< Interface::FITKUnstructuredMeshVTK>();
            if (meshDataFASTSIM == nullptr)return false;
            Interface::FITKMeshVTKManagerFASTSIM* manager = meshDataFASTSIM->getBoundaryMeshManager();
            manager->clear();
            meshDataFASTSIM->clearMesh();


            //清除求解器参数中对应的边界
            auto physicsData = FITKAPP->getGlobalData()->getPhysicsData<Interface::FITKOFPhysicsData>();
            if (physicsData) {
                auto boundaryManager = physicsData->getBoundaryManager();
                if (boundaryManager)boundaryManager->clear();
            }
            
            //如果当前界面是求解器边界参数界面，清除界面
            if (_mainWindow == nullptr) return false;
            GUI::BoundaryWidget* boundWidget = dynamic_cast<GUI::BoundaryWidget*>(_mainWindow->getPropertyWidget()->getCurrentWidget());
            if (boundWidget) {
                _mainWindow->getPropertyWidget()->init();
            }

            //刷新
            treeOper->updateTree();
            graphOper->reRender();
        }
        else if(actionName == "ClearItemMesh") {
            // 获取objID
            auto arg = _operArgs.value("objID");

            Interface::FITKUnstructuredMeshVTK* meshDataFASTSIM = FITKAPP->getGlobalData()->getMeshDataFASTSIM< Interface::FITKUnstructuredMeshVTK>();
            if (meshDataFASTSIM == nullptr)return false;
            Interface::FITKMeshVTKManagerFASTSIM* manager = meshDataFASTSIM->getBoundaryMeshManager();
            for (int i = 0; i < manager->getDataCount(); i++) {
                Interface::FITKUnstructuredMeshVTK* boundMesh = manager->getDataByIndex(i);
                if(boundMesh->getDataObjectID() == arg) {
                    manager->removeDataObj(boundMesh);
                }
            }
            //刷新
            treeOper->updateTree();
            graphOper->reRender();
        }
        else if(actionName == "actionResetName") {
            // 获取objID
            auto arg = _operArgs.value("objID");
            QDialog* dialog = nullptr;

            Interface::FITKUnstructuredMeshVTK* meshDataFASTSIM = FITKAPP->getGlobalData()->getMeshDataFASTSIM< Interface::FITKUnstructuredMeshVTK>();
            if (meshDataFASTSIM == nullptr)return false;
            Interface::FITKMeshVTKManagerFASTSIM* manager = meshDataFASTSIM->getBoundaryMeshManager();
            for (int i = 0; i < manager->getDataCount(); i++) {
                Interface::FITKUnstructuredMeshVTK* boundMesh = manager->getDataByIndex(i);
                if(boundMesh->getDataObjectID() == arg) {
                    dialog = new GUI::MeshResetNameDialog(this, boundMesh,i);
                    connect(dialog, SIGNAL(sigResetNameFinish()), this, SLOT(slotResetNameFinish()));
                    if (dialog) {
                        dialog->show();
                    }
                    return false;
                }
            }
            emit FITKAPP->getSignalTransfer()->outputMessageSig(3, tr("Warning :  An error occurred during renaming !!!"));
        }
        else if(actionName == "actionAssembly"){
            QWidget* widget = nullptr;
            Interface::FITKUnstructuredMeshVTK* meshDataFASTSIM = FITKAPP->getGlobalData()->getMeshDataFASTSIM< Interface::FITKUnstructuredMeshVTK>();
            if (meshDataFASTSIM == nullptr)return false;

            widget = new GUI::MeshAssemblyDialog(this, meshDataFASTSIM);
            connect(widget, SIGNAL(sigAssemblyFinish()), this, SLOT(slotAssemblyFinish()));

            if (mainWindow->getPropertyWidget() && widget) {
                propertyWidget->setWidget(widget);
            }
            return false;
        }
        return true;
    }

    bool OperatorsMeshManager::execProfession()
    {
        return true;
    }
    void OperatorsMeshManager::readMesh()
    {
        Interface::FITKOFGeometryData* geometryData = FITKAPP->getGlobalData()->getGeometryData<Interface::FITKOFGeometryData>();
        int nModel = geometryData->getDataCount();
        QString namestl ="";
         QStringList namelist;
        for (int i = 0; i < nModel; i++)
        {
            Interface::FITKAbsGeoCommand* model = geometryData->getDataByIndex(i);
            if (model != nullptr)
            {

                namestl=model->getDataObjectName();

                namelist.insert(i, namestl);
            }
        }
        // 获取单例
        auto meshGen = Interface::FITKMeshGenInterface::getInstance();
        // 读取网格
       // auto meshProcessor = meshGen->getMeshProcessor();
        auto meshProcessor = meshGen->getMeshProcessorFASTSIM();
        if (meshProcessor == nullptr) return;

        //工作路径获取
        QString workDir = "";
        if (FITKAPP->getAppSettings()) {
            workDir = FITKAPP->getAppSettings()->getWorkingDir();
        }
        if (workDir.isEmpty()) workDir = QApplication::applicationDirPath() + "/../WorkDir";

if (namestl.contains("Two")) {
        for (int i = 0; i < namelist.size(); ++i) {
        //网格划分路径指定
        QString meshGenDir = workDir + "/case/constant/geometry/"+ namelist[i]+".vtk";
        meshProcessor->setValue("WorkDir", meshGenDir);
        meshProcessor->start();

     }
}else {
    //网格划分路径指定
    QString meshGenDir = workDir + "/case/constant/geometry/"+ namestl+".vtk";
    meshProcessor->setValue("WorkDir", meshGenDir);
    meshProcessor->start();

        }


        // 获取模型树控制器
        auto treeOper = Core::FITKOperatorRepo::getInstance()->getOperatorT<EventOper::TreeEventOperator>("ModelTreeEvent");
        if (treeOper == nullptr) return;
        EventOper::GraphEventOperator* graphOper = FITKOPERREPO->getOperatorT<EventOper::GraphEventOperator>("GraphPreprocess");
        if (graphOper == nullptr)return;

        // 网格对象
        auto mesh = FITKAPP->getGlobalData()->getMeshDataFASTSIM<Interface::FITKUnstructuredMeshVTK>();
        if(mesh==nullptr) return;
        Interface::FITKMeshVTKManagerFASTSIM* manager = mesh->getBoundaryMeshManager();
        for (int i = 0; i < manager->getDataCount(); i++) {
            Interface::FITKUnstructuredMeshVTK* boundMesh = manager->getDataByIndex(i);
            if (boundMesh == nullptr)continue;
            graphOper->updateGraph(boundMesh->getDataObjectID());
        }
        //graphOper->updateGraph(objID);
        treeOper->updateTree();
        graphOper->reRender(true);
    }

    void OperatorsMeshManager::slotResetNameFinish()
    {
        EventOper::GraphEventOperator* graphOper = FITKOPERREPO->getOperatorT<EventOper::GraphEventOperator>("GraphPreprocess");
        if (graphOper == nullptr)return;
        // 获取模型树控制器
        auto treeOper = Core::FITKOperatorRepo::getInstance()->getOperatorT<EventOper::TreeEventOperator>("ModelTreeEvent");
        if (treeOper == nullptr) return;

        treeOper->updateTree();
        graphOper->reRender();
    }

    void OperatorsMeshManager::slotAssemblyFinish()
    {
        EventOper::GraphEventOperator* graphOper = FITKOPERREPO->getOperatorT<EventOper::GraphEventOperator>("GraphPreprocess");
        if (graphOper == nullptr)return;
        // 获取模型树控制器
        auto treeOper = Core::FITKOperatorRepo::getInstance()->getOperatorT<EventOper::TreeEventOperator>("ModelTreeEvent");
        if (treeOper == nullptr) return;

        treeOper->updateTree();
        graphOper->reRender();
    }
}
